package com.ruoyi.heatwork.demotcp.tcp;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.HexUtil;
import com.google.common.collect.Maps;
import com.ruoyi.heatwork.demotcp.rest.DeviceConstant;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.net.NetClient;
import io.vertx.core.net.NetClientOptions;
import io.vertx.core.net.NetSocket;
import io.vertx.core.parsetools.RecordParser;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;


@Slf4j
@AllArgsConstructor
@NoArgsConstructor
public class TcpClient extends AbstractVerticle {


    private Integer port;

    private String ip;

    private Integer subNum;

    public final static Map<String, NetSocket> CLIENT_MAP = Maps.newHashMap();


    @Override
    public void start() throws Exception {
        NetClientOptions options = new NetClientOptions()
                .setConnectTimeout(5000)
                .setTcpKeepAlive(true)
                .setIdleTimeout(0);  // 禁用空闲超时
        NetClient client = vertx.createNetClient(options);
        connectToServer(client);

    }

    private void connectToServer(NetClient client) {
        client.connect(port, ip, res -> {
            if (res.succeeded()) {
                log.info("连接成功=====》");
                NetSocket socket = res.result();
                // 设置每5分钟发送心跳
                vertx.setPeriodic(105 * 60 * 1000, timerId -> {
                    String numHex = SerialTools.toHex(subNum);
                    numHex = numHex.length() == 1 ? "0" + numHex : numHex;
                    //根据分站类型，如果是老分站要发4次，新分站只发一次。TODO: 2022/4/25
                    String check = SerialTools.makeCheckSum(String.format(DeviceConstant.HEX_CHECK_FORMAT, numHex));
                    String sendMsg = String.format(DeviceConstant.HEX_SEND_FORMAT, numHex, check);
                    log.info("发送心跳=====》 {}", sendMsg);
                    Buffer buffer = Buffer.buffer();
                    socket.write(Buffer.buffer(HexUtil.decodeHex(sendMsg))).onComplete(ar1 -> {
                        if (ar1.succeeded()) {
                            final RecordParser parser = RecordParser.newDelimited(Buffer.buffer(HexUtil.decodeHex("EE")), receive -> {
                                buffer.appendBuffer(receive);
                                if (buffer.length() >= 4000) {
                                    // 处理缓冲区溢出
//                                    handleBufferOverflow(socket, buffer);
                                }
                                String heartStr =  HexUtil.encodeHexStr(receive.getBytes(), false).toUpperCase();
                                log.info("接收到TCP消息11111 {}", heartStr);
                                if (heartStr.startsWith(DeviceConstant.HEX_SEND_START) || heartStr.startsWith(DeviceConstant.HEX_SEND1_START)) {
                                    int receiveIndex = heartStr.indexOf("CABD");
                                    String substationNum = heartStr.substring(receiveIndex + 4, receiveIndex + 6);
                                    // 数据分析
//                                    dataAnalysis(String.format("%sEE", heartStr), String.valueOf(HexUtil.hexToInt(substationNum)), socket);
                                    ThreadUtil.sleep(2000);
                                }
                            });
                            socket.handler(parser);
                        } else {
                            // 处理发送失败的情况
                            log.error("发送失败==========》{} {}", sendMsg, socket.writeHandlerID());
                        }
                    });
                });

                CLIENT_MAP.put(socket.writeHandlerID(), socket);
                socket.handler(buffer1 -> {
                    String heartStr =  HexUtil.encodeHexStr(buffer1.getBytes(), false).toUpperCase();
                    log.info("接收到TCP消息 {}", heartStr);
                });
                // 处理连接关闭事件
                socket.closeHandler(v -> {
                    log.error("Connection closed");
                    // 重新连接
                    reconnect(client);
                });
            }
        });
    }

    private void reconnect(NetClient netClient) {
        log.info("Reconnecting...");
        // 延迟一段时间后重新连接
        vertx.setTimer(5000, id -> connectToServer(netClient));
    }


}
